package com.nightpiter.controller.algorithms;

import com.nightpiter.model.objects.Line;
import com.nightpiter.model.objects.Transfer;
import com.nightpiter.model.objects.Transition;

/**
 * Edge class for Dijkstra's Algorithm
 * 
 * Package protected
 * 
 * @author Eldar Abusalimov (eldar.abusalimov@gmail.com)
 */
class Edge extends Way {

	/**
	 * the transition which is represented by this Edge
	 */
	private Transition transition = null;

	/**
	 * the starting vertex
	 */
	Vertex fromVertex;

	/**
	 * the ending vertex
	 */
	Vertex toVertex;

	/**
	 * public constructor
	 * 
	 * @param transition
	 *            the transition which is represented by this Edge
	 * @param fromVertex
	 *            the starting vertex
	 * @param toVertex
	 *            the ending vertex
	 */
	public Edge(Transition transition, Vertex fromVertex, Vertex toVertex) {
		this.transition = transition;
		this.fromVertex = fromVertex;
		this.toVertex = toVertex;
		if (transition instanceof Transfer) {
			super.set(0, 0, transition.getTime(), 1);
		} else {
			// if instance of Tunnel
			super.set(transition.getTime(), 1, 0, 0);
		}
		fromVertex.addEdge(this);
	}

	/**
	 * public constructor (creating the edge between two vertices representing
	 * the same multiline station)
	 * 
	 * @param line
	 *            the line which is used to determine trains delay
	 * @param fromVertex
	 *            the starting vertex
	 * @param toVertex
	 *            the ending vertex
	 */
	public Edge(Line line, Vertex fromVertex, Vertex toVertex) {
		assert fromVertex.getStation() == toVertex.getStation();
		this.fromVertex = fromVertex;
		this.toVertex = toVertex;
		super.set(0, 0, line.getTrainDelay() / 2, 1);
		fromVertex.addEdge(this);
	}

	/**
	 * public constructor (could be used for creating temporary zero-valued
	 * instances without adding itself to fromVertex's outgoing edges list)
	 * 
	 * @param fromVertex
	 *            the starting vertex
	 * @param toVertex
	 *            the ending vertex
	 */
	public Edge(Vertex fromVertex, Vertex toVertex) {
		assert fromVertex.getStation() == toVertex.getStation();
		this.fromVertex = fromVertex;
		this.toVertex = toVertex;
		super.set(0, 0, 0, 0);
	}

	/**
	 * @return the transition
	 */
	public Transition getTransition() {
		return transition;
	}

	/**
	 * @return the fromVertex
	 */
	public Vertex getFromVertex() {
		return fromVertex;
	}

	/**
	 * @return the toVertex
	 */
	public Vertex getToVertex() {
		return toVertex;
	}

}
